package com.moss.cloud.auth.biz.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.moss.cloud.auth.biz.mapper.SysMenuMapper;
import com.moss.cloud.auth.biz.service.ISysMenuService;
import com.moss.cloud.auth.biz.service.ISysRoleMenuService;
import com.moss.cloud.auth.biz.service.ISysUserService;
import com.moss.cloud.common.base.model.po.SysMenu;
import com.moss.cloud.common.base.model.po.SysRoleMenu;
import com.moss.cloud.common.core.constant.Constant;
import com.moss.cloud.common.core.enums.MenuType;
import com.moss.cloud.common.core.model.po.PermissionMenu;
import com.moss.cloud.common.core.model.vo.UserInfo;
import com.moss.cloud.common.core.utils.BooleanHandel;
import com.moss.cloud.common.security.component.RedisTemplateOps;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 菜单业务实现
 *
 * @author 今年
 * @date 2023年11月8日
 */
@Service
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> implements ISysMenuService {

    private ISysUserService sysUserService;
    private ISysRoleMenuService sysRoleMenuService;
    private RedisTemplateOps redisTemplateOps;

    public SysMenuServiceImpl(ISysUserService sysUserService,
                              ISysRoleMenuService sysRoleMenuService,
                              RedisTemplateOps redisTemplateOps) {
        this.sysUserService = sysUserService;
        this.sysRoleMenuService = sysRoleMenuService;
        this.redisTemplateOps = redisTemplateOps;
    }

    /**
     * 根据用户登录账号获取用户授权的资源列表
     *
     * @param username
     * @return
     */
    @Override
    public void queryByUsername(String username) {
        //根据用户id(账号，手机号，邮箱账号)查询到用户所拥有的角色
        UserInfo user = sysUserService.userInfo(username);
        BooleanHandel.isTrue(Objects.nonNull(user) && CollectionUtils.isNotEmpty(user.getRoleIds())).trueHandle(() -> {
            //根据角色列表查询到角色的资源的关联
            List<SysRoleMenu> roleMenus = sysRoleMenuService.list(new QueryWrapper<SysRoleMenu>()
                    .lambda()
                    .in(SysRoleMenu::getRoleId, user.getRoleIds()));
            //根据资源列表查询出所有资源对象
            List<Long> roleMenuIds = roleMenus.stream()
                    .map(SysRoleMenu::getMenuId).collect(Collectors.toList());
            BooleanHandel.isTrue(CollectionUtils.isNotEmpty(roleMenuIds)).trueHandle(() -> {
                List<SysMenu> sysMenus = this.list(new QueryWrapper<SysMenu>().lambda()
                        .in(SysMenu::getId, roleMenuIds));
                List<PermissionMenu> menus = convertPermissionMenu(sysMenus);
                redisTemplateOps.set(Constant.USER_SYS_MENU + username, menus);
            });
        });
    }

    /**
     * 初始化菜单资源
     */
    @Override
    public void loadSysMenu() {
        List<SysMenu> sysMenus = this.list(new QueryWrapper<SysMenu>().lambda()
                .eq(SysMenu::getMenuType, MenuType.BTN.getCode()));
        List<PermissionMenu> menus = convertPermissionMenu(sysMenus);
        BooleanHandel.isTrue(CollectionUtils.isNotEmpty(menus)).trueHandle(() ->
                menus.parallelStream().forEach(item ->
                        redisTemplateOps.set(Constant.SYS_MENU_KEY + item.getPath() + "_" + item.getMethod(), item)));
    }

    /**
     * 数据转换
     *
     * @param sysMenus
     * @return
     */
    private List<PermissionMenu> convertPermissionMenu(List<SysMenu> sysMenus) {
        return CollectionUtils.isNotEmpty(sysMenus) ? sysMenus.stream().map(item -> {
            PermissionMenu menu = new PermissionMenu();
            BeanUtils.copyProperties(item, menu);
            return menu;
        }).collect(Collectors.toList()) : Collections.emptyList();
    }


}
